<?php

namespace liketp\database\concern;

use PDO;

trait TableStruct
{
    /**
     * tables = [
     *      table1 => [
     *          fields => [
     *              field1 => [ data_type => '', column_type => '', bindType => ...],
     *              field2 => [ data_type => '', column_type => '' ...]
     *          ],
     *          primaryKey => field | [f1, f2] | null
     *      ],
     *      table2 => [
     *          ...
     *      ]
     * ]
     */
    protected $tables = [];

    protected $paramTypeMap = [
        PDO::PARAM_INT => ['tinyint', 'smallint', 'mediumint', 'int', 'integer', 'bigint'],
        PDO::PARAM_STR => ['char', 'varchar', 'text', 'enum', 'float', 'decimal', 'date', 'datetime', 'timestamp'],
    ];

    public function pk(string $table = '')
    {
        $tableInfo = $this->tableInfo($table);
        return $tableInfo['primaryKey'];
    }

    public function tableInfo(string $table = '')
    {
        $table = $table ?: $this->getTableName();

        if (isset($this->tables[$table]) == false) {

            $query = $this->createQuery($this, ['connect']);
            $sql = "SHOW FULL COLUMNS FROM `$table`";
            $list = $query->query($sql);

            [$fields, $primaryKey] = $this->formatFields($list);
            $primaryKey = count($primaryKey) > 1 ? $primaryKey : ($primaryKey[0] ?? null);
            $this->tables[$table]['fields'] = $fields;
            $this->tables[$table]['primaryKey'] = $primaryKey;
        }

        return $this->tables[$table];
    }

    protected function formatFields(array $fieldList)
    {
        $fields = [];
        $primaryKey = [];

        foreach ($fieldList as $field) {
            $field = array_change_key_case($field);
            $type = preg_replace('/\(.*/', '', $field['type']);
            $item = [
                'name' => $field['field'],
                'type' => $type,
                'fullType' => $field['type'],
                'notNull' => 'NO' == $field['null'],
                'default' => $field['default'],
                'primary' => 'PRI' == $field['key'],
                'autoinc' => 'auto_increment' == $field['extra'],
                'comment' => $field['comment'],
                'paramType' => $this->paramType($type),
            ];
            $fields[$item['name']] = $item;
            if ($item['primary']) array_push($primaryKey, $item['name']);
        }
        return [$fields, $primaryKey];
    }

    protected function paramType($type)
    {
        $res = PDO::PARAM_STR;
        foreach ($this->paramTypeMap as $k => $list) {
            if (in_array($type, $list)) $res = $k;
        }
        return $res;
    }
}
